package com.example.db;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONObject;
import com.example.model.Date;
import com.example.model.Item;
import com.example.model.ItemList;
import com.example.model.User;
import com.example.model.UserList;
import android.app.Activity;
import android.os.AsyncTask;
import android.util.Log;

/**
 * This class will be the main point of contact between the database and the
 * app. It will load the users and items from the database to the app, and it
 * will update the database with new items and users as the list grows.
 * 
 * @author 3Factorial
 */
public class db extends Activity {

	private String url = "http://www.passionpath.co/cs2340/test.php";

	private String newUser;
	private String newPassword;
	private String newAdmin;

	private String newName;
	private String newLocation;
	private String newDescription;
	private String newTags;
	private String newImages;
	private String newCreator;
	private String newDate;
	private String newLost;

	/**
	 * Adds a user to the database.
	 * 
	 * @param u
	 *            User name
	 * @param p
	 *            User password
	 * @param a
	 *            Admin determination
	 */
	public void addUser(String u, String p, String a) {
		newUser = u;
		newPassword = p;
		newAdmin = a;
		url = "http://www.passionpath.co/cs2340/addUser.php";
		new addUserTask().execute();
	}

	/**
	 * Helper class to add users to the database through HTTP.
	 */
	class addUserTask extends AsyncTask<Void, Void, Void> {

		InputStream is = null;

		@Override
		protected Void doInBackground(Void... params) {
			// the data to send
			ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			nameValuePairs.add(new BasicNameValuePair("user", newUser));
			nameValuePairs.add(new BasicNameValuePair("pass", newPassword));
			nameValuePairs.add(new BasicNameValuePair("isAdmin", newAdmin));

			// http post
			try {
				HttpClient httpclient = new DefaultHttpClient();
				HttpPost httppost = new HttpPost(url);
				httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
				HttpResponse response = httpclient.execute(httppost);
				HttpEntity entity = response.getEntity();
				is = entity.getContent();
			} catch (Exception e) {
				Log.e("log_tag", "Error in http connection " + e.toString());
			}

			return null;
		}
	}

	/**
	 * Adds an item to the database.
	 * 
	 * @param name
	 *            Item's name
	 * @param location
	 *            Item's location
	 * @param description
	 *            Item's description
	 * @param tags
	 *            Item's tags
	 * @param images
	 *            Items' images
	 * @param creator
	 *            Item's creator
	 * @param date
	 *            Item's date of creation
	 * @param lost
	 *            Item's status
	 */
	public void addItem(String name, String location, String description,
			String tags, String images, String creator, String date, String lost) {
		newName = name;
		newLocation = location;
		newDescription = description;
		newTags = tags;
		newImages = images;
		newCreator = creator;
		newDate = date;
		newLost = lost;
		url = "http://www.passionpath.co/cs2340/addItem.php";
		new addItemTask().execute();
	}

	/**
	 * Helper class to add items to the database through HTTP.
	 */
	class addItemTask extends AsyncTask<Void, Void, Void> {

		InputStream is = null;

		@Override
		protected Void doInBackground(Void... params) {
			// the data to send
			ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			nameValuePairs.add(new BasicNameValuePair("name", newName));
			nameValuePairs.add(new BasicNameValuePair("location", newLocation));
			nameValuePairs.add(new BasicNameValuePair("description",
					newDescription));
			nameValuePairs.add(new BasicNameValuePair("tags", newTags));
			nameValuePairs.add(new BasicNameValuePair("images", newImages));
			nameValuePairs.add(new BasicNameValuePair("creator", newCreator));
			nameValuePairs.add(new BasicNameValuePair("date", newDate));
			nameValuePairs.add(new BasicNameValuePair("lost", newLost));

			// http post
			try {
				HttpClient httpclient = new DefaultHttpClient();
				HttpPost httppost = new HttpPost(url);
				httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
				HttpResponse response = httpclient.execute(httppost);
				HttpEntity entity = response.getEntity();
				is = entity.getContent();
			} catch (Exception e) {
				Log.e("log_tag", "Error in http connection " + e.toString());
			}

			return null;
		}
	}

	/**
	 * Retrieves the list of users and their information from the database.
	 * 
	 * @param u
	 *            The UserList to add all the database users to.
	 */
	public void getUsers(UserList u) {
		url = "http://www.passionpath.co/cs2340/getUsers.php";
		new getUsersTask().execute(u);
	}

	/**
	 * Helper class to retrieve the users from the database using HTTP
	 */
	class getUsersTask extends AsyncTask<UserList, Void, String> {

		InputStream is = null;
		String postResult = "";

		@Override
		protected String doInBackground(UserList... params) {
			UserList u = params[0];
			// http post
			try {
				HttpClient httpclient = new DefaultHttpClient();
				HttpPost httppost = new HttpPost(url);
				HttpResponse response = httpclient.execute(httppost);
				HttpEntity entity = response.getEntity();
				is = entity.getContent();
			} catch (Exception e) {
				Log.e("log_tag", "Error in http connection " + e.toString());
			}

			// convert response to string
			try {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(is, "iso-8859-1"), 8);
				StringBuilder sb = new StringBuilder();
				String line = null;
				while ((line = reader.readLine()) != null) {
					sb.append(line + "\n");
				}
				is.close();

				postResult = sb.toString();
			} catch (Exception e) {
				Log.e("log_tag", "Error converting result " + e.toString());
			}

			// parse json data
			try {
				JSONArray jArray = new JSONArray(postResult);
				for (int i = 0; i < jArray.length(); i++) {
					JSONObject json_data = jArray.getJSONObject(i);
					User tmp = new User(json_data.getString("user"),
							json_data.getString("pass"));
					if (json_data.getInt("isAdmin") == 1) {
						tmp.setIsAdmin(true);
					} else {
						tmp.setIsAdmin(false);
					}
					u.add(tmp);
				}

			} catch (Exception e) {
				Log.e("log_tag", "Error parsing data " + e.toString());
			}

			return postResult;
		}

		protected void onPostExecute(String result) {
			Log.i("users", "result: " + result);
		}
	}

	/**
	 * Retrieves all the created items from the database.
	 * 
	 * @param it
	 *            Item list in which to place all items.
	 */
	public void getItems(ItemList it) {
		url = "http://www.passionpath.co/cs2340/getItems.php";
		new getItemsTask().execute(it);
	}

	/**
	 * Helper class to retrieve all items from the database using HTTP.
	 */
	class getItemsTask extends AsyncTask<ItemList, Void, String> {

		InputStream is = null;
		String postResult = "";

		@Override
		protected String doInBackground(ItemList... params) {
			ItemList il = params[0];
			// http post
			try {
				HttpClient httpclient = new DefaultHttpClient();
				HttpPost httppost = new HttpPost(url);
				HttpResponse response = httpclient.execute(httppost);
				HttpEntity entity = response.getEntity();
				is = entity.getContent();
			} catch (Exception e) {
				Log.e("log_tag", "Error in http connection " + e.toString());
			}

			// convert response to string
			try {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(is, "iso-8859-1"), 8);
				StringBuilder sb = new StringBuilder();
				String line = null;
				while ((line = reader.readLine()) != null) {
					sb.append(line + "\n");
				}
				is.close();

				postResult = sb.toString();
			} catch (Exception e) {
				Log.e("log_tag", "Error converting result " + e.toString());
			}

			// parse json data
			try {
				JSONArray jArray = new JSONArray(postResult);
				for (int i = 0; i < jArray.length(); i++) {
					JSONObject json_data = jArray.getJSONObject(i);
					String name = json_data.getString("name");
					String description = json_data.getString("description");
					String location = json_data.getString("location");
					User usr = new User("", "");// FIX ME
					Date date = new Date(0, 0, 0);// FIX ME
					int lost = json_data.getInt("lost");
					Item tmp = new Item(name, description, location, usr, date,
							lost);
					il.add(tmp);
				}

			} catch (Exception e) {
				Log.e("log_tag", "Error parsing data " + e.toString());
			}

			return postResult;
		}

		protected void onPostExecute(String result) {
			Log.i("users", "result: " + result);
		}
	}
}
